package com.zhy.sping.service.impl;

import com.zhy.sping.config.ElastConfig;
import com.zhy.sping.dao.SearchHistoryDao;
import com.zhy.sping.entity.SearchHistory;
import com.zhy.sping.es.dao.CourseDocumentDao;
import com.zhy.sping.es.entity.CourseDocument;
import com.zhy.sping.service.intf.CourseDocumentService;
import com.zhy.sping.vo.R;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CourseDocumentServiceImpl implements CourseDocumentService {
    @Autowired
    private ElasticsearchRestTemplate template;
    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private SearchHistoryDao historyDao;
    @Autowired
    private CourseDocumentDao documentDao;

    @Value("${excellent.test.start}")
    private int start;
    @Override
    public R suggest(int uid, String msg) {
        historyDao.save(new SearchHistory(uid,msg,new Date()));
        List<String> list=new ArrayList<>();
        //1.创建搜索建议查询对象
        CompletionSuggestionBuilder s1=new CompletionSuggestionBuilder("name.suggest");
        CompletionSuggestionBuilder s2=new CompletionSuggestionBuilder("teaname.suggest");
        //2.设置搜索建议的信息
        s1.prefix(msg).size(20);
        s2.prefix(msg).size(20);
        //3.创建查询对象
        SuggestBuilder suggest=new SuggestBuilder();
        //添加搜索建议对象
        suggest.addSuggestion("namesug",s1);
        suggest.addSuggestion("teanamesug",s2);

        //4.执行查询 获取查询结果
        SearchResponse response=template.suggest(suggest, IndexCoordinates.of(ElastConfig.ELAST_NAME));
        //5.获取搜索建议的查询结果
        addSuggest(list,response,"namesug");
        addSuggest(list,response,"teanamesug");
        return R.ok("OK",list);
    }

    private void addSuggest(List<String> list, SearchResponse response, String name){
        //5.获取搜索建议的查询结果
        Suggest.Suggestion suggestion=response.getSuggest().getSuggestion(name);
        //6.遍历实体类对象
        for(Object e:suggestion.getEntries()){
            Suggest.Suggestion.Entry entry= (Suggest.Suggestion.Entry) e;
            //遍历搜索建议选项对象
            for(Object o:entry.getOptions()){
                Suggest.Suggestion.Entry.Option option= (Suggest.Suggestion.Entry.Option) o;
                //获取搜索建议的查询结果
                list.add(option.getText().toString());
            }
        }
    }


    @Override
    public R queryHost() {
        List<String> list=new ArrayList<>();
        // 根据指定字段进行分组,对应的docCount就是 文档中出现的次数
        TermsAggregationBuilder teamAgg1 = AggregationBuilders.terms("hotWords_count").field("name.keyword");
        teamAgg1.order(BucketOrder.count(true));
        TermsAggregationBuilder teamAgg2 = AggregationBuilders.terms("hotWords_count").field("teaname.keyword");
        teamAgg2.order(BucketOrder.count(true));
        SearchResponse searchResp;
        try {
            //创建查询请求对象，并设置请求信息
            SearchRequest searchRequests = new SearchRequest(ElastConfig.ELAST_NAME);
            //searchRequests.types();
            searchRequests.searchType(org.elasticsearch.action.search.SearchType.DFS_QUERY_THEN_FETCH);
            SearchSourceBuilder sourceBuilders = new SearchSourceBuilder();
            sourceBuilders.aggregation(teamAgg1);
            sourceBuilders.aggregation(teamAgg2);
            sourceBuilders.from(0);
            sourceBuilders.size(10);
            sourceBuilders.explain(true);
            searchRequests.source(sourceBuilders);
            //执行查询请求
            searchResp = client.search(searchRequests, RequestOptions.DEFAULT);
            //获取查询次数信息
            Aggregations aggregations=searchResp.getAggregations();
            Terms terms=aggregations.get("hotWords_count");
            for(Terms.Bucket b:terms.getBuckets()){
                // b.getDocCount();查询匹配成功的次数
                list.add(b.getKeyAsString());
            }
            //遍历查询结果
//            SearchHits searchHits=searchResp.getHits();
//            for(SearchHit sh:searchHits.getHits()){
//                list.add(JSON.parseObject(sh.getSourceAsString(),CourseDocument.class);
//            }
            //logger.info("热词查询");
            return R.ok("OK",list);
        } catch (Exception e) {
            //logger.error("热词查询出现了异常");
            return R.fail("网络故障");
        }
    }

    @Override
    public R saveAll(int count) {
        for (int i =1;i<=count;i++){
            start++;
            documentDao.save(new CourseDocument(start,"test-"+i,"lx-"+i));
        }
        return R.ok("ok",null);
    }
}
